package com.hup.utils.commons;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;

/**
 * @author hugan
 * @date 2019/8/24
 */
public class JavaUtil {

    /**
     * 获取某个对象的继承接口的泛型;
     *
     * @param obj 实例化对象
     * @param clz 该对象所继承的某个接口类
     * @return 目标接口类的泛型
     */
    public static Type[] getInterfaceType(Object obj, Class<?> clz) {
        //继承的接口信息,长度等于继承的接口数
        Type[] gis = obj.getClass().getGenericInterfaces();
        for (Type gi : gis) {
            if (gi instanceof ParameterizedType) {
                //继承的接口类
                Type rawType = ((ParameterizedType) gi).getRawType();
                boolean assignableFrom = clz.isAssignableFrom((Class<?>) rawType);
                if (assignableFrom) {
                    return ((ParameterizedType) gi).getActualTypeArguments();
                }
            }
        }
        throw new IllegalArgumentException(obj.getClass().getSimpleName() + "对象无继承"
                + clz.getSimpleName() + "接口类:" + Arrays.toString(gis));
    }

    /**
     * 只适合用在接口default方法中,用在一般方法上时只会返回第一个继承接口类;
     * 根据某接口的实现类,获取该接口的实现泛型类别
     *
     * @param obj default方法中传入this,代表该接口的实现类的实例化对象
     * @return 泛型数组
     * @deprecated 这方法不应该使用, 得到的是第一个接口类(按代码书写顺序);
     * 如果实现类是继承了多个接口,则拿到的type是无法安全的
     */
    @Deprecated
    public static Type[] getSelfInterfaceType(Object obj) {
        //继承的接口信息,长度等于继承的接口数
        Type[] gis = obj.getClass().getGenericInterfaces();
        for (Type gi : gis) {
            if (gi instanceof ParameterizedType) {
                return ((ParameterizedType) gi).getActualTypeArguments();
            }
        }
        throw new IllegalArgumentException("找不到接口泛型:" + Arrays.toString(gis));
    }

    public enum JdkBitType {
        Bit32("x32", "32"),
        Bit64("x64", "64");

        private final String desc;
        private final String sunArchDataModel;

        JdkBitType(String desc, String sunArchDataModel) {
            this.desc = desc;
            this.sunArchDataModel = sunArchDataModel;
        }

        @Override
        public String toString() {
            return desc;
        }

        /**
         * @return {@link #Bit32},{@link #Bit64}
         */
        public static JdkBitType getJdkBitType() {
            String strVal = System.getProperty("sun.arch.data.model");
            if (Bit32.sunArchDataModel.equals(strVal)) {
                return Bit32;
            } else if (Bit64.sunArchDataModel.equals(strVal)) {
                return Bit64;
            }
            throw new IllegalArgumentException("获取JDK处理版本异常:" + strVal);
        }

    }

}
